package cn.pconline.autoclub.service;

import cn.pconline.autoclub.entity.Club;
import cn.pconline.autoclub.entity.ClubIntegral;
import cn.pconline.autoclub.entity.ClubMember;
import cn.pconline.autoclub.entity.Topic;
import cn.pconline.autoclub.entity.TopicImage;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.Pager;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;

/**
 * 车友会帖子服务层
 */
public class TopicService {

    private static final Logger log = LoggerFactory.getLogger(TopicService.class);
    @Autowired
    private ClubService clubService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private PetrolService petrolService;
    @Autowired
    private GeliDao geliDao;
    @Autowired
    private GeliOrm geliOrm;
    @Autowired
    private PagerService pagerService;
    @Autowired
    private UserLimitService limitService;
    @Autowired
    private UserService userService;

    /**
     * 获取帖子列表（没有组装用户对象）
     *
     * @param clubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Topic> getTopics(int type, long clubId, int pageNo, int pageSize) {
        if (pageNo <= 0 || pageSize <= 0 || clubId <= 0) {
            return Pager.buildEmptyPager();
        }

        Club club = clubService.getClub(clubId);
        if (club == null) {
            return Pager.buildEmptyPager();
        }

        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.appendSql("select id from ").appendSql(geliOrm.getTableName(Topic.class, clubId));
        sqlBuilder.appendSql(" where club_id=").appendValue(club.getClubId());
        if (type == 2) {
            sqlBuilder.appendSql(" and pick >0 ");
        }
        sqlBuilder.appendSql(" order by create_date desc");
        return pagerService.pager(Topic.class, clubId, sqlBuilder, pageNo, pageSize);
    }

    /**
     * 获取有组装用户的帖子分页
     *
     * @param clubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Topic> getTopicsWithUsers(int type, long clubId, int pageNo, int pageSize) {
        Pager<Topic> topicPager = getTopics(type, clubId, pageNo, pageSize);
        List<Topic> topics = topicPager.getResultList();
        if (topics != null && !topics.isEmpty()) {
            long[] authorIds = new long[topics.size()];
//            long[] lastPostByIds = new long[topics.size()];

            for (int i = 0; i < topics.size(); i++) {
                Topic topic = topics.get(i);
                if (topic != null) {
                    authorIds[i] = topic.getUserId();
//                    lastPostByIds[i] = topic.getLastPostBy();
                }
            }

            List<User> authors = geliDao.list(User.class, authorIds);
//            List<User> lastPostBys = geliDao.list(User.class, lastPostByIds);

            for (int i = 0; i < topics.size(); i++) {
                Topic topic = topics.get(i);
                if (topic != null) {
                    User author = authors.get(i);
//                    User lastPostAuthor = lastPostBys.get(i);
                    topic.setTopicAuthor(author == null ? User.ANONYMOUS : author);
//                    topic.setLastPostAuthor(lastPostAuthor == null ? User.ANONYMOUS : lastPostAuthor);
                }
            }
        }

        return topicPager;
    }

    public Topic find(long topicId, long clubId) {
        SqlBuilder sqlBuilder = new SqlBuilder();
        sqlBuilder.appendSql("select * from ").appendSql(geliOrm.getTableName(Topic.class, clubId))
                .appendSql(" where club_id=").appendValue(clubId)
                .appendSql(" and topic_id=").appendValue(topicId);
        return geliDao.findFirst(Topic.class, sqlBuilder.getSql(), sqlBuilder.getValues());
    }

    public int createTopicImage(List<TopicImage> images) {
        for (TopicImage i : images) {
            geliDao.create(i);
        }
        return images.size();
    }

    public void updateTopicImage(List<TopicImage> images) {
        if (images == null || images.isEmpty()) {
            return;
        }
        deleteTopicImage(images.get(0).getTopicId());
        createTopicImage(images);
    }

    public int deleteTopicImage(long topicId) {
        List<TopicImage> list = getImagesByTopicId(topicId, 0);
        int update = 0;
        for (TopicImage t : list) {
            geliDao.delete(t, t.getImageId());
        }
        return update;
    }

    /**
     * 创建车友会帖子
     *
     * @param topic
     * @return
     */
    public long createTopic(Topic topic) {
        ClubIntegral commonTopicPetrol = petrolService.getById(
                PetrolService.ADD_PERSONAL_PETROL_ITEM_TOPIC); // 油值表
        Club club = clubService.getNormalClub(topic.getClubId());
        int petrol = commonTopicPetrol.getPetrol() < 0 ? commonTopicPetrol.getPetrol() : club == null ? 0 : commonTopicPetrol.getPetrol();
        topic.setPetrol(petrol);
        long id = geliDao.create(topic);
        topic.setId(id);
        ClubMember clubMember = memberService.findMember(topic.getUserId(), topic.getClubId());

        //如果帖子恢复为精华帖，加精华分数
        if (topic.getPick() > 0) {
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_PICK);
            int pickPetrol = club == null ? 0 : i.getPetrol();
            topic.setPetrol(pickPetrol);
            geliDao.update(topic, "petrol");
            petrolService.addToPersonWithinLimit(clubMember, (int) i.getIntegralId(), pickPetrol, i.getName(), false, false);
        }

        //如果帖子恢复为推荐帖，加推荐分数
        if (topic.getRecommend() > 0) {
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_RECOMMEND);
            int recommendPetrol = club == null ? 0 : i.getPetrol();
            topic.setPetrol(recommendPetrol);
            geliDao.update(topic, "petrol");
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), recommendPetrol, i.getName(), false, false);
        }
        petrolService.addToPersonWithinLimit(clubMember, commonTopicPetrol.getIntegralId(),
                petrol, commonTopicPetrol.getName(), true, true);
        return id;
    }

    /**
     * 物理删除某会员在某车友会下的所有帖子（这个操作没有减少分数）
     *
     * @param userId
     * @param clubId
     */
    public void batchDeleteTopic(long userId, long clubId) {
        String baseSql = "DELETE FROM %s WHERE user_id = %s and club_id = %s";
        String sql = String.format(baseSql, "ac_topic_" + clubId % 10, userId, clubId);
        String[] sqls = new String[1];
        sqls[0] = sql;
        geliDao.getJdbcTemplate().batchUpdate(sqls);
    }

    /**
     * 删除车友会帖子
     *
     * @param topicId
     * @param clubId
     */
    public void deleteTopic(long topicId, long clubId) {
        Topic topic = find(topicId, clubId);
        if (topic != null) {
            geliDao.delete(topic, topic.getId());
            ClubMember clubMember = memberService.findMember(topic.getUserId(), clubId);

            //如果被删帖子是精华帖，则减精华分数
            if (topic.getPick() > 0) {
                ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_PICK_CANCEL);
                petrolService.addToPersonWithinLimit(clubMember,
                        (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
            }

            //如果被删帖子是推荐帖，则减推荐分数
            if (topic.getRecommend() > 0) {
                ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_RECOMMEND_CANCEL);
                petrolService.addToPersonWithinLimit(clubMember,
                        (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
            }

            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_TOPIC_DELETE);
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
            limitService.update(clubMember.getUid(), i.getPetrol()); // 更新今日油值限制
        }
    }

    /**
     * 设置精华
     *
     * @param topicId
     * @param clubId
     */
    public void setPick(long topicId, long clubId) {
        Topic topic = find(topicId, clubId);
        Club club = clubService.getNormalClub(clubId);
        if (topic != null && topic.getPick() != 1) {
            topic.setPick(1);
            ClubMember clubMember = memberService.findMember(topic.getUserId(), clubId);
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_PICK);
            int petrol = club == null ? 0 : i.getPetrol();
            topic.setPetrol(topic.getPetrol() + petrol);
            geliDao.update(topic, "pick,petrol");
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), petrol, i.getName(), false, false);
        }
    }

    /**
     * 取消精华
     *
     * @param topicId
     * @param clubId
     */
    public void removePick(long topicId, long clubId) {
        Topic topic = find(topicId, clubId);
        if (topic != null && topic.getPick() == 1) {
            ClubMember clubMember = memberService.findMember(topic.getUserId(), clubId);
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_PICK_CANCEL);
            topic.setPick(0);
            int petrol = topic.getPetrol() + i.getPetrol();
            topic.setPetrol(petrol < 0 ? 0 : petrol);
            geliDao.update(topic, "pick,petrol");
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
        }
    }

    /**
     * 设置推荐
     *
     * @param topicId
     * @param clubId
     */
    public void setRecommend(long topicId, long clubId) {
        Topic topic = find(topicId, clubId);
        if (topic != null && topic.getRecommend() != 1) {
            Club club = clubService.getNormalClub(clubId);
            ClubMember clubMember = memberService.findMember(topic.getUserId(), clubId);
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_RECOMMEND);
            topic.setRecommend(1);
            int petrol = club == null ? 0 : i.getPetrol();
            topic.setPetrol(topic.getPetrol() + petrol);
            geliDao.update(topic, "recommend,petrol");
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), petrol, i.getName(), false, false);
        }
    }

    /**
     * 取消推荐
     *
     * @param topicId
     * @param clubId
     */
    public void removeRecommend(long topicId, long clubId) {
        Topic topic = find(topicId, clubId);
        if (topic != null && topic.getRecommend() == 1) {
            ClubMember clubMember = memberService.findMember(topic.getUserId(), clubId);
            ClubIntegral i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_RECOMMEND_CANCEL);
            topic.setRecommend(0);
            int petrol = topic.getPetrol() + i.getPetrol();
            topic.setPetrol(petrol < 0 ? 0 : petrol);
            geliDao.update(topic, "recommend,petrol");
            petrolService.addToPersonWithinLimit(clubMember,
                    (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
        }
    }

    /**
     * 回复主题，添加回复数和油值,移动端回复分为两倍
     *
     * @param topicId
     * @param clubId
     */
    public void replyTopic(long topicId, long clubId, long postUserId, Date lastPostAt) {
        Topic topic = find(topicId, clubId);
        if (topic != null) {
            topic.setPostCount(topic.getPostCount() + 1);
            topic.setLastPostAt(lastPostAt);
            topic.setLastPostBy(postUserId);
            topic.setLastPostName(userService.getNickNameByUserId(postUserId));
            geliDao.update(topic, "post_count,last_post_at,last_post_by,last_post_name");
        }
    }

    /**
     * 删除回复
     *
     * @param clubId
     * @param postUserId
     * @param agent
     */
    public void delReplyTopicPetrol(long clubId, long postUserId, int agent) {
        ClubMember clubMember = memberService.findMember(postUserId, clubId);
        ClubIntegral i;
        if (agent <= 0) {
            i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_POST_DELETE);
        } else {
            i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_POST_WAP_DELETE);
        }
        petrolService.addToPersonWithinLimit(clubMember,
                (int) i.getIntegralId(), i.getPetrol(), i.getName(), false, false);
        limitService.update(postUserId, i.getPetrol()); // 更新今日油值限制
    }

    /**
     * 增加回复
     *
     * @param clubId
     * @param postUserId
     * @param agent
     */
    public void addReplyTopicPetrol(long clubId, long postUserId, int agent) {
        ClubMember clubMember = memberService.findMember(postUserId, clubId);
        ClubIntegral i;
        if (agent <= 0) {
            i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_POST);
        } else {
            i = petrolService.getById(PetrolService.ADD_PERSONAL_PETROL_ITEM_POST_WAP);
        }
        petrolService.addToPersonWithinLimit(clubMember, i.getIntegralId(), i.getPetrol(), i.getName(), true, true);
    }

    /**
     * 回帖被删除，移动端回复分为两倍
     *
     * @param topicId
     * @param clubId
     */
    public void deletePost(long topicId, long clubId, long postUserId) {
        Topic topic = find(topicId, clubId);
        if (topic != null) {
            topic.setPostCount(Math.max(topic.getPostCount() - 1, 0));
            geliDao.update(topic, "post_count");
        }
    }

    /**
     * 更新帖子内容
     *
     * @param topic
     */
    public void updateTopic(long topicId, long clubId, String topicTitle, String message,
            String image1, String image2, String image3) {
        Topic topic = find(topicId, clubId);
        if (topic != null) {
            topic.setTopicTitle(topicTitle);
            topic.setMessage(message);
            topic.setImage1(image1);
            topic.setImage2(image2);
            topic.setImage3(image3);
            geliDao.update(topic, "topic_title,message,image1,image2,image3");
        } else {
            log.error("topic not exists[{},{}]", topicId, clubId);
        }
    }

    /**
     * 根据车友会ID统计帖子数量
     *
     * @param clubId
     * @return
     */
    public int countByClubId(long clubId) {
        if (clubId < 1) {
            return 0;
        }
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select count(1) from ").appendSql(geliOrm.getTableName(Topic.class, clubId));
        sql.appendSql(" where club_id = ").appendValue(clubId);
        return geliDao.count(sql.getSql(), sql.getValues());
    }

    /**
     * 查询车友会精华帖
     *
     * @param clubId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Topic> listPick(long clubId, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select id from ").appendSql(geliOrm.getTableName(Topic.class, clubId)).appendSql(" where pick=1");
        return pagerService.pager(Topic.class, sql, pageNo, pageSize);
    }

    /**
     * num为0时，表示不限制
     *
     * @param topicId
     * @param clubId
     * @param num
     * @return
     */
    public List<TopicImage> getImagesByTopicId(long topicId, long num) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select image_id from ").appendSql(geliOrm.getTableName(TopicImage.class, topicId));
        sql.appendSql(" where topic_id = ").appendValue(topicId);
        sql.appendSql(" order by seq asc");
        if (num > 0) {
            sql.appendSql(" limit ").appendValue(num);
        }
        try {
            return geliDao.list(TopicImage.class, topicId, sql.getSql(), sql.getValues());
        } catch (EmptyResultDataAccessException e) {
            return Collections.emptyList();
        }
    }
}
